﻿using Xejen.Communication.Configuration;
using Xejen.Communication.Endpoints;
using Xejen.Communication.Http;
using Xejen.Communication.Http.Configuration;
using Xejen.Communication.Soap;
using Xejen.Communication.Soap.Communicator;
using Xejen.Communication.Soap.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml.XPath;

namespace Xejen.Communication.Test
{
    public partial class MainForm : Form
    {
        private ISoapCommunicator _communicator;
        public MainForm(ISoapCommunicator communicator)
        {
            _communicator = communicator;

            //以下3种方式均可以注册心跳检测逻辑
            //第1种：
            //communicator.Heartbeat.LocalHeartbeatCheck = () =>
            //{
            //    Debug.WriteLine($"本地心跳检测时间：{DateTime.Now.ToString()}");
            //    byte[] buffer = Guid.NewGuid().ToByteArray();
            //    var value = BitConverter.ToInt64(buffer, 0);

            //    return value % 2 == 1;
            //};
            //communicator.Heartbeat.RemoteHeartbeatCheck = () =>
            //{
            //    Debug.WriteLine($"远端心跳检测时间：{DateTime.Now.ToString()}");
            //    byte[] buffer = Guid.NewGuid().ToByteArray();
            //    var value = BitConverter.ToInt64(buffer, 0);

            //    return value % 2 == 0;
            //};
            //第2种
            //communicator.Heartbeat.RegisterHeartbeatChecker(new HeartbeatChecker());
            //第3种
            communicator.Heartbeat.RegisterHeartbeatChecker<HeartbeatConfig, HeartbeatChecker>();

            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            _communicator.Heartbeat.LocalAliveChanged += (object sender, AliveStatusEventArgs args) =>
            {
                Debug.WriteLine($"设备是否在线：{args.CurrentStatus}");

                Invoke((MethodInvoker)(() =>
                {
                    LocalAliveLabel.Text = args.CurrentStatus.ToString();
                }));
            };
            _communicator.Heartbeat.RemoteAliveChanged += (object sender, AliveStatusEventArgs args) =>
            {
                Debug.WriteLine($"远端是否在线：{args.CurrentStatus}");

                Invoke((MethodInvoker)(() =>
                {
                    RemoteAliveLabel.Text = args.CurrentStatus.ToString();
                }));
            };
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //#region 原始的请求方式，全部api自己构建
            //SoapConfig config = new SoapConfig() { };
            //SoapRequestHandler<WebServiceInvoker, SoapConfig, WebServiceAddress> handle = new SoapRequestHandler<WebServiceInvoker, SoapConfig, WebServiceAddress>();

            //SoapCommunicator<WebServiceInvoker, WebServiceAddress> communicator = new SoapCommunicator<WebServiceInvoker, WebServiceAddress>(config, new WebServiceInvokerCreator(), handle);
            //var result1 = await communicator.RequestAsync(new SoapCommunicationAddress<WebServiceAddress>
            //{
            //    RequestAddress = new Address<WebServiceAddress>
            //    {
            //        Value = new WebServiceAddress
            //        {
            //            RequestUri = "http://192.168.24.25:15000/WebServiceMesDemo.asmx",
            //            ClassName = "WebServiceMesDemo",
            //            MethodName = "addition",
            //        }
            //    }
            //}, new List<object> { 1.25, 3.64 }, 3000, default);

            //var result2 = await communicator.RequestAsync<List<object>>(new SoapCommunicationAddress<WebServiceAddress>
            //{
            //    RequestAddress = new Address<WebServiceAddress>
            //    {
            //        Value = new WebServiceAddress
            //        {
            //            RequestUri = "http://192.168.24.25:15000/WebServiceMesDemo.asmx",
            //            ClassName = "WebServiceMesDemo",
            //            MethodName = "multiition",
            //        }
            //    }
            //}, new List<object> { 3, 4 });

            //var returnData = result2.ReturnData;
            //#endregion
        }

        /// <summary>
        /// 代码正常可测试asmx
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button2_Click(object sender, EventArgs e)
        {
            //for (; ; )
            //{
            #region 使用依赖注入的方式构建请求
            var address = new SoapAddress
            {
                RequestUri = "http://192.168.3.164:5000/WeatherForecast",
            };
            var result1 = await _communicator.GetServiceAsync(address);

            var result2 = await _communicator.PostServiceAsync(new SoapAddress
            {
                RequestUri = "http://192.168.3.164:5000/WeatherForecast/add",
            }, 3);

            if (result2.IsSuccess)
            {
                var returnData = result2.DataToString();
            }
            #endregion

            //    await Task.Delay(1);
            //}
        }

        private async void button3_Click(object sender, EventArgs e)
        {
            // 构建请求体参数
            string equipmentCode = "1021-CV-EL-00068";
            string resourceCode = "CV-ZYBH2115";
            string localTime = "2020-01-15T10:10:00";
            string operatorUserID = "EQUtest01";
            string operatorPassword = "1";

            // 构建SOAP请求消息体
            string soapBody = $@"
            <soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                <soap:Header>
                    <LoginSoapHeader xmlns=""http://tempuri.org/"">
                        <EquUserID>EQUtest01</EquUserID>
                        <EquPassword>1</EquPassword>
                        <OperatorUserID>{operatorUserID}</OperatorUserID>
                        <OperatorPassword>{operatorPassword}</OperatorPassword>
                    </LoginSoapHeader>
                </soap:Header>
                <soap:Body>
                    <OperatorLogin xmlns=""http://tempuri.org/"">
                        <model>
                            <EquipmentCode>{equipmentCode}</EquipmentCode>
                            <ResourceCode>{resourceCode}</ResourceCode>
                            <LocalTime>{localTime}</LocalTime>
                            <OperatorUserID>{operatorUserID}</OperatorUserID>
                            <OperatorPassword>{operatorPassword}</OperatorPassword>
                        </model>
                    </OperatorLogin>
                </soap:Body>
            </soap:Envelope>";

            var result2 = await _communicator.PostServiceAsync(new SoapAddress
            {
                RequestUri = "http://122.195.53.162:7008/EquWebService80/EquToMes/EquToMesOperatorLogin.asmx?op=OperatorLogin",
            }, soapBody, new SoapConfig
            {
                Enable = _communicator.Config.Enable,
                ContentType = "text/xml",
                EncodingName = _communicator.Config.EncodingName,
                Timeout = _communicator.Config.Timeout,
                JsonSerializerOptions = _communicator.Config.JsonSerializerOptions,
                //Headers = new System.Collections.Specialized.NameValueCollection
                //{
                //    {"EquUserID","EQUtest01" },
                //    {"EquPassword","1" },
                //    {"OperatorUserID","EQUtest01" },
                //    {"OperatorPassword","1" },
                //}
            });

            if (result2.IsSuccess)
            {
                var str = result2.DataToString();
                SoapResponseParser parser = new SoapResponseParser();
                MesResult result = parser.ParseResponse<MesResult>(str);
            }
        }

        public class OperatorLoginResult
        {
            public int Code { get; set; }
        }

        private async void button4_Click(object sender, EventArgs e)
        {
            //测试通过。注意：XML 声明必须是文档中的第一个节点并且在它之前不允许出现空白字符。
            string soapBody = $@"<?xml version=""1.0"" encoding=""utf-8""?>
            <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
              <soap:Header>
                <LoginSoapHeader xmlns=""http://tempuri.org/"">
                  <EquUserID>admin</EquUserID>
                  <EquPassword>admin123</EquPassword>
                </LoginSoapHeader>
              </soap:Header>
              <soap:Body>
                <HelloWorld xmlns=""http://tempuri.org/"">
                  <body>
                    <EquipmentCode>string</EquipmentCode>
                  </body>
                </HelloWorld>
              </soap:Body>
            </soap:Envelope>";

            var result2 = await _communicator.PostServiceAsync(new SoapAddress
            {
                RequestUri = "http://192.168.3.164:112/WebService1.asmx?op=HelloWorld",
            }, soapBody, new SoapConfig
            {
                Enable = _communicator.Config.Enable,
                ContentType = "text/xml",
                EncodingName = _communicator.Config.EncodingName,
                Timeout = _communicator.Config.Timeout,
                JsonSerializerOptions = _communicator.Config.JsonSerializerOptions,
                //Headers = new System.Collections.Specialized.NameValueCollection
                //{
                //    {"EquUserID","admin" },
                //    {"EquPassword","admin123" },
                //}
            });

            if (result2.IsSuccess)
            {
                var str = result2.DataToString();
                SoapResponseParser parser = new SoapResponseParser();
                MesResult result = parser.ParseResponse<MesResult>(str);
            }
        }

        public class MesResult
        {
            /// <summary>
            /// 执行代码    INT
            /// </summary>
            public int Code { get; set; }
            /// <summary>
            /// 返回信息 STRING
            /// </summary>
            public string Msg { get; set; }
        }

        private async void button5_Click(object sender, EventArgs e)
        {
            // 构建请求体参数
            string equipmentCode = "1021-CV-EL-00068";
            string resourceCode = "CV-ZYBH2115";
            string localTime = "2020-01-15T10:10:00";
            string operatorUserID = "EQUtest01";
            string operatorPassword = "1";

            // 构建SOAP请求消息体
            string soapBody = $@"<?xml version=""1.0"" encoding=""utf-8""?>
            <soap12:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope"">
              <soap12:Header>
                <LoginSoapHeader xmlns=""http://tempuri.org/"">
                  <EquUserID>EQUtest01</EquUserID>
                  <EquPassword>1</EquPassword>
                  <OperatorUserID>{operatorUserID}</OperatorUserID>
                  <OperatorPassword>{operatorPassword}</OperatorPassword>
                </LoginSoapHeader>
              </soap12:Header>
              <soap12:Body>
                <OperatorLogin xmlns=""http://tempuri.org/"">
                  <model>
                    <EquipmentCode>{equipmentCode}</EquipmentCode>
                    <ResourceCode>{resourceCode}</ResourceCode>
                    <LocalTime>{localTime}</LocalTime>
                    <OperatorUserID>{operatorUserID}</OperatorUserID>
                    <OperatorPassword>{operatorPassword}</OperatorPassword>
                  </model>
                </OperatorLogin>
              </soap12:Body>
            </soap12:Envelope>";

            var result2 = await _communicator.PostServiceAsync(new SoapAddress
            {
                RequestUri = "http://122.195.53.162:7008/EquWebService80/EquToMes/EquToMesOperatorLogin.asmx?op=OperatorLogin",
            }, soapBody, new SoapConfig
            {
                Enable = _communicator.Config.Enable,
                ContentType = "application/soap+xml",
                EncodingName = _communicator.Config.EncodingName,
                Timeout = _communicator.Config.Timeout,
                JsonSerializerOptions = _communicator.Config.JsonSerializerOptions,
            });

            if (result2.IsSuccess)
            {
                var str = result2.DataToString();
            }
        }

        private async void button6_Click(object sender, EventArgs e)
        {
            var result2 = await _communicator.PostServiceAsync(new SoapAddress
            {
                RequestUri = "http://192.168.24.25:15000/WebServiceMesDemo.asmx/addition",
            }, "i=21&j=34", new SoapConfig
            {
                Enable = _communicator.Config.Enable,
                ContentType = "application/x-www-form-urlencoded",
                EncodingName = _communicator.Config.EncodingName,
                Timeout = _communicator.Config.Timeout,
                JsonSerializerOptions = _communicator.Config.JsonSerializerOptions,
            });// new Dictionary<string, string> { { "i", "21" }, { "j", "34" } });

            if (result2.IsSuccess)
            {
                var str = result2.DataToString();
            }
        }

        private async void button7_Click(object sender, EventArgs e)
        {
            var result = await _communicator.GetServiceAsync(new SoapAddress
            {
                RequestUri = "http://192.168.24.25:15000/WebServiceMesDemo.asmx/addition?i=22&j=75",
            });
        }

        private async void button8_Click(object sender, EventArgs e)
        {
            //测试通过。注意：XML 声明必须是文档中的第一个节点并且在它之前不允许出现空白字符。
            string soapBody = $@"<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
  <soap:Body>
    <TestCommand1 xmlns=""http://tempuri.org/"">
      <input>
        <Software>上位机软件名称：SLFmwKtrMl</Software>
        <EquipmentCode>设备编号：IlIjL</EquipmentCode>
        <SerialNos>
            <RequestCommand_CELLINPUT_SerialNos>
              <SerialNo>gvmSeJtosL</SerialNo>
              <GetProductTypeFlag>true</GetProductTypeFlag>
            </RequestCommand_CELLINPUT_SerialNos>
            <RequestCommand_CELLINPUT_SerialNos>
              <SerialNo>WImdjWYGvm</SerialNo>
              <GetProductTypeFlag>false</GetProductTypeFlag>
            </RequestCommand_CELLINPUT_SerialNos>
            <RequestCommand_CELLINPUT_SerialNos>
              <SerialNo>GrgwLozzVD</SerialNo>
              <GetProductTypeFlag>true</GetProductTypeFlag>
            </RequestCommand_CELLINPUT_SerialNos></SerialNos>
      </input>
    </TestCommand1>
  </soap:Body>
</soap:Envelope>";
            var wrapper = new SoapAddress
            {
                RequestUri = "http://192.168.3.164:224/WebService2.asmx?op=TestCommand1",
            };

            var result2 = await _communicator.PostServiceAsync(wrapper, soapBody, new SoapConfig
            {
                Enable = _communicator.Config.Enable,
                ContentType = "text/xml; charset=utf-8",
                EncodingName = _communicator.Config.EncodingName,
                Timeout = _communicator.Config.Timeout,
                JsonSerializerOptions = _communicator.Config.JsonSerializerOptions,
            });

            if (result2.IsSuccess)
            {
                var str = result2.DataToString();
                SoapResponseParser parser = new SoapResponseParser();
                MesResult result = parser.ParseResponse<MesResult>(str);
            }
            else
            {
                var errMessage = result2.Exception.InnerAggregateMessage();
            }
        }
    }
}
